import {
  IDomainEntities,
  IDomainEntity,
  IDomainInfo,
  IFireAndInfo,
} from "@@/typings/deduct-control";
import {
  CustomViewer,
  IAnimation,
  IAnimationGroup,
} from "../CustomCesium/CustomCesium";
import {
  Cartesian3,
  Color,
  Entity,
  HeightReference,
  JulianDate,
  SampledPositionProperty,
  TimeInterval,
  TimeIntervalCollection,
  defined,
} from "cesium";
import moment from "moment";

export default class DomainUtils {
  /// 根据记录返回新的状态
  private static getNewProperty(positions: {
    time: JulianDate[];
    data: Cartesian3[];
  }) {
    const position = new SampledPositionProperty(),
      timeInterval = new TimeInterval({
        start: positions.time[1],
        stop: positions.time[length - 1],
      }),
      timeIntervalCollection = new TimeIntervalCollection();
    timeIntervalCollection.addInterval(timeInterval);
    /// 位置时间序列
    position.addSamples(positions.time, positions.data);

    return { position, timeIntervalCollection };
  }

  static updatePath(
    customViewer: CustomViewer,
    animationGroup: IAnimationGroup,
    step: IFireAndInfo,
    visualAngle: string,
    type: string
  ) {
    const entities: IDomainEntities = {},
      /// 初始时间戳
      startStampTime = step.simul_time * 1000,
      startJulianTime = JulianDate.fromDate(moment(startStampTime).toDate()),
      endJulianTime = JulianDate.addMinutes(
        startJulianTime,
        1,
        new JulianDate()
      ),
      timeInterval = new TimeInterval({
        start: startJulianTime,
        stop: endJulianTime,
      }),
      timeIntervalCollection = new TimeIntervalCollection([timeInterval]);

    animationGroup.removeAll();

    Object.keys(step.entities).forEach((key) => {
      const stepEntity = step.entities[key];
      const entity = animationGroup.datasource.entities.getById(key + ""),
        cartesian3 = Cartesian3.fromDegrees(
          stepEntity.position?.longitude || 0,
          stepEntity.position?.latitude || 0
        );
      if (defined(cartesian3)) {
        if (entity) {
          const properties = entity.properties?.getValue(startJulianTime),
            positions = properties.positions;
          if (positions) {
            positions.time.push(startJulianTime);
            positions.data.push(cartesian3);

            const newState = this.getNewProperty(positions);
            entity.position = newState.position;
          }
        } else {
          const maxDistance = getMaxDistance(
            type,
            stepEntity.sensorInfo,
            stepEntity.weaponInfo
          );
          if (maxDistance == null) {
            return;
          }
          let newEntity = this.createEntity(
              {
                id: key + "",
                side: visualAngle,
                maxDistance: maxDistance,
                positions: { time: [startJulianTime], data: [cartesian3] },
              },
              visualAngle,
              type,
              timeIntervalCollection
            ),
            animation =
              newEntity &&
              customViewer.animationManager?.createAnimation(newEntity);

          // 剔除无效数据
          if (animation)
            animation.id != `undefined` && animationGroup.add(animation);
        }
      }
    });
  }
  /**
   * 初始创建路径
   * @param customViewer
   * @param step
   * @param visualAngle 视角
   */
  static createInitDomain(
    customViewer: CustomViewer,
    step: IFireAndInfo,
    visualAngle: string,
    type: string
  ) {
    const entities: IDomainEntities = {},
      animations: IAnimation[] = [],
      /// 初始时间戳
      startStampTime = step.simul_time * 1000,
      startJulianTime = JulianDate.fromDate(moment(startStampTime).toDate()),
      endJulianTime = JulianDate.addMinutes(
        startJulianTime,
        1,
        new JulianDate()
      ),
      timeInterval = new TimeInterval({
        start: startJulianTime,
        stop: endJulianTime,
      }),
      timeIntervalCollection = new TimeIntervalCollection([timeInterval]);

    Object.keys(step.entities).forEach((key) => {
      this.addEntityInfo(
        entities,
        key,
        step.entities[key],
        type,
        visualAngle,
        startJulianTime
      );
    });

    // 根据实体创建动画
    for (const key in entities) {
      if (Object.prototype.hasOwnProperty.call(entities, key)) {
        const entityInfo = entities[key],
          entity = this.createEntity(
            entityInfo,
            visualAngle,
            type,
            timeIntervalCollection
          ),
          animation =
            entity && customViewer.animationManager?.createAnimation(entity);
        // 剔除无效数据
        animation?.entity.id != `undefined` &&
          animation &&
          animations.push(animation);
      }
    }
    return {
      animations,
      period: { startTime: startJulianTime, endTime: endJulianTime },
    };
  }

  static addEntityInfo(
    entities: IDomainEntities,
    key: string,
    model: IDomainInfo,
    type: string,
    side: string,
    currentTime: JulianDate
  ) {
    const { position, sensorInfo, weaponInfo } = model,
      cartesian3 = Cartesian3.fromDegrees(
        position?.longitude || 0,
        position?.latitude || 0
      );
    if (!defined(cartesian3)) return;

    let maxDistance = getMaxDistance(type, sensorInfo, weaponInfo);
    if (maxDistance === null) {
      return;
    }

    /// 已存在实体信息，则继续添加旋转、位置数据
    if (entities[key]) {
      const entity = entities[key];
      /// 位置
      entity.positions.time.push(currentTime);
      entity.positions.data.push(cartesian3);
      entity.maxDistance = maxDistance;
    }
    /// 添加新实体信息
    else {
      const positions: { time: JulianDate[]; data: Cartesian3[] } = {
        time: [],
        data: [],
      };
      /// 位置
      positions.time.push(currentTime);
      positions.data.push(cartesian3);
      entities[key] = {
        id: key,
        side: side,
        maxDistance,
        positions,
      };
    }
  }

  /**
   * 创建实体
   * @param entityInfo
   */
  private static createEntity(
    entityInfo: IDomainEntity,
    visualAngel: string,
    type: string,
    availability?: TimeIntervalCollection
  ) {
    let maxDistance;
    let distance;
    let rgba =
        visualAngel == "red"
          ? Color.ORANGE
          : Color.fromCssColorString("#FA00A3");
    if (type == "info") {
      maxDistance = entityInfo.maxDistance * 100;
    } else {
      // rgba = visualAngel == "red" ? Color.RED : Color.WHITE;
      maxDistance = entityInfo.maxDistance * 1000000;
    }
    if (maxDistance > 60000000) {
      return null;
      // if (entityInfo.maxDistance > (60000000 / 2)) {
      //   distance = 500;
      // } else {
      //   distance = entityInfo.maxDistance;
      // }
    } else {
      distance = maxDistance
    }

    /// 动画步长为1
    let position: Cartesian3 | SampledPositionProperty =
      entityInfo.positions.data[0];
    /// 动画步长超过1
    if (entityInfo.positions.data.length > 1) {
      position = new SampledPositionProperty();
      /// 位置时间序列
      position.addSamples(entityInfo.positions.time, entityInfo.positions.data);
    }
    const resourceEntity = new Entity({
      id: entityInfo.id,
      position,
      ellipse: {
        semiMajorAxis: distance,
        semiMinorAxis: distance,
        material: rgba.withAlpha(0.5),
        heightReference: HeightReference.CLAMP_TO_GROUND,
      },
    });
    return resourceEntity;
  }
}

function getMaxDistance(type, sensorInfo, weaponInfo) {
  let maxDistance = null;
  if (type == "info") {
    if (
      sensorInfo.m_MaxDetectDistance == undefined ||
      sensorInfo.m_MaxDetectDistance == null
    ) {
      return maxDistance;
    }
    maxDistance = sensorInfo.m_MaxDetectDistance;
  } else {
    if (
      weaponInfo.m_MaxAttackDistance == undefined ||
      weaponInfo.m_MaxAttackDistance == null
    ) {
      return maxDistance;
    }
    maxDistance = weaponInfo.m_MaxAttackDistance;
  }
  return maxDistance;
}
